优秀架构师是如何学习开源项目的?
The following article is from 波波微课 Author 架构师杨波
一、前言
大家好,我是架构师杨波,大家都叫我波波老师。
波波可以说是一个不折不扣的开源爱好者,在一线企业工作时,波波就花费大量的时间和精力,研究和学习开源代码。即便现在转入技术培训行业,波波仍然会花大量时间,研究github上的开源项目。另外,波波业余时间也开发一些开源小项目。可以这样说,波波今天之所以能够成长为一个资深软件架构师,开源项目对我的帮助是非常大的。
近年,波波在极客时间上输出一些技术课程,这些课程大部分都是基于开源项目开发的。输出过程中,经常有学员会问我该如何高效学习开源项目的问题。为了解答学员的疑问,基于自己这十几年来学习开源项目的经验,我总结出了学习开源项目的一个方法论。这个方法论包括6个层次和8大方法,下面是这个方法论的一个总结表格:
上面的表格中的内容很多,可能一下子看不明白,不用着急,波波后面会依次讲解每一种方法。而且在每一种方法中,我都会给出项目案例,其中还包括行业优秀的工程师/架构师,学习开源项目的一些方法和思路。
二、方法
方法1 ~ 直接看源码
我们先来看第一层的方法1,如下表所示:
方法1很好理解,就是直接看源码,当然也包括看文档,还有跑跑样例代码。
如果项目代码本身比较简单,完全可以直接看代码。举个例子,波波最近正在开发一门《分布式系统案例课》,期间需要深入研究一下一致性Hash算法。于是,我就在github上找了一个项目[链接见上图]~一个用Java开发的一致性Hash算法的演示项目。这个项目比较简单,源代码就没有几个,当然直接看代码,再跑跑样例就可以理解了。
方法1一般是没有直接产出的。当然,在工作或学习中,最好还是带着实际问题去看代码,理解了代码再回头来解决实际问题,相当于有一个产出。这样可以形成一个闭环,提升学习效果。如果你没有问题,直接纯看代码学习,效果会差很多。
方法1处在第1层,最简单,学习效果一般,能学到的主要就是源代码阅读能力。为了和后面的方法做比较,我把方法1的学习效果假定为1~2,作为一个基准学习效果。
方法2 ~ 整理源代码
方法2叫整理源代码,它更进一步到第2层,如下表所示:
怎么理解呢方法2呢?其实它指的是将开源项目的源代码统统整理一遍,包括将包名都改掉,并且编译、测试和运行通过。
方法2是波波研究开源项目代码的习惯。举个例子,前段时间我要学习一下Spring Boot项目开发,于是我就在github上找到了一个叫spring-petclinic(宠物医院)的项目[链接见上图]。spring-petclinic是一个经典的Spring框架演示项目,它正好有一个Spring Boot的版本。为了深入学习这个项目,我把它的整个源码都整理了一遍,包括将包名全部改成com.spring2go,有些地方的代码还做了调整和简化。然后,我把项目调试运行通过。最后,我还把整理过的代码放在了我的github/spring2go站点上[链接见上图]。
如果你不对外输出分享的话,方法2一般也是没有直接产出的。通过方法2,你可以获得细粒度的源码阅读和调试技能,因为你必须一行行整理代码,包括单元测试,并且还要调试运行通过。这个做法比简单看代码的粒度肯定更细,学习效果也更好,可以算2~3的效果。当然,方法2耗费时间也更多。
方法3 ~ 整理+输出分享
方法3叫整理+输出分享,它更进一步到第3层,如下表所示:
方法3是指在方法2整理过源代码的基础上,总结梳理出源码分析或者架构设计类的文档或PPT或视频,在公司或者社区分享。
方法3也是波波阅读开源项目代码的习惯,之前在企业是这样,现在做课程输出也是这样。举个例子,波波前段时间要重温一下Spring Cloud微服务技术栈,于是我就在github上找到一个叫spring-petclinic-microservices的项目[链接见上图],它是spring-petclinic项目的微服务版。为了深入学习这个项目,我先用方法2,把整个项目的源码整理了一遍,并输出在我的github/spring2go站点上[链接见上图]。然后,我自己录制了一个视频课程,名称《Spring Cloud微服务应用》,并且把整个视频分享在我的B站空间上[链接见上图]。这个工作做完,我不仅加深了对Spring Cloud相关技术栈和框架的理解,同时还产出了两样东西,一个项目源码+一个视频课程,这两样东西最后变成了我的个人积累和沉淀。
再举一个方法3的例子。我之前在拍拍贷担任技术总监的时候,期间招聘了一些应届毕业生。作为培训和个人学习习惯培养的一部分,我要求他们每月写一篇源码分析或者技术学习类文章,并且发表在团队的技术博客上[链接见上图],并且这些文章输出是计入绩效考核的。我认为,早期对工程师的定期输出习惯的培养是非常重要的。
方法3一般是有产出的,它的学习效果比方法2还要好,可以达到3~5的学习效果。因为你有产出并且分享以后,就有机会获得学习效果的反馈。这种反馈甚至是可以量化的,比方说github上项目的stars或者是issues,还有B站上视频的点击量、点赞数和评论等。这些反馈非常宝贵,可以帮助你优化改进你的学习。即便你只是在公司内部分享,同事一般也会给你反馈。另外,方法3不仅可以提升你的技术技能,同时可以提升你的整理、输出和分享技能,甚至还有内容制作技能。比方说,通过B站视频课程输出,波波就初步掌握了视频制作和编辑技能。这种内容制作和输出技能,在当下社会同样重要。
下面再讲两个来自YouTube,通过输出分享提升个人技能的例子。这两个例子和开源并不直接相关,但是同样值得参考借鉴。
第一个例子来自一个叫Dylan Israel的美国人,他在Youtube上的频道就叫Dylan Israel,主要内容是关于如何自学编程的。他本人不是科班出身,完全通过自学编程掌握技术。他主要通过美国的Code Cademy和FreeCodeCamp等站点学习技术,每次学习一门课程或技术,他就把自己学习的过程,以live coding(现场编程)的方式,制作成视频,并分享在YouTube的个人频道上。目前他在企业上班,年薪大致在美金6位数,业余时间继续搞他的Youtube频道,既通过视频输出提升自己的技能,同时也分享编程技能。目前他的YouTube频道有74.4k订阅,也是不错的。
第二个例子来自一个叫Caleb Curry的美国人,他在Youtube上的频道就叫Caleb Curry,主要内容是关于编程语言学习的。Caleb学习编程语言的方式,就是每学习一种语言,就输出一门该语言的视频课程,并分享在YouTube上,也就是通过视频输出来提升学习效率。通过这种方式,经过超过6年的持续输出,他目前已经掌握了几乎所有主流的编程语言,包括Python/Java/C/C#/C++/JavaScript/SQL等。同时,他在YouTube上的视频内容也变成了他的个人资产积累。目前,他的YouTube频道有超过225k订阅,在技术领域,这个订阅量已经比较牛逼了。
方法4 ~ 开发克隆版
下面是方法4,叫开发克隆版,它同样在第3层,如下表所示:
方法4指的是开发原项目的克隆版,这个和书籍翻译有点类似,比方说,原项目是用go语言开发的,我就克隆出一个Java语言版,并且分享到开源社区。
方法4也是波波使用过的方法,学习效果也很不错,当然耗费时间也更多。比方说,波波去年在极客时间上输出了一门课程《Spring Boot与Kubernetes云原生微服务实践》,为了开发这门课程,我在github上找到了一个叫Staffjoy的项目[链接见上图]。Staffjoy是一个工时排班(scheduling)应用,原来是一家创业公司的SaaS产品,后来公司关闭就把项目给开源了。这个项目是用go语言开发的,采用微服务架构,总体质量还不错(毕竟是创业公司面向企业的项目)。于是,我花了近2.5个月的时间,深入研究了这个项目的源码,并且用Java/Spring技术对这个项目进行了克隆(也适当做了调整和简化),最后开源在我的github/spring2go站点上[链接见上图]。通过这次克隆,波波不仅进一步学习了Spring和微服务等技术,同时还产出了一个课程产品,当前在极客时间上已经有超过6k的订阅量。
方法4的例子还有很多。比方说,业界知名的开源消息队列Kafka,就有不少克隆版。其中有一个叫jafka[链接见上图],它是在6~7年前,由一个叫Andy Liu的搜狐架构师开发的,波波6~7年前也学习过他的这个项目。因为Kafka是Scala写的,Andy Liu的就把它克隆成Java版,所以取名就叫jafka。Kafka本身还是比较复杂的,深入理解它的源码并不容易,但是Andy Liu通过克隆的方式去学习kafka,同时还产出了一个jafka,可以认为他已经完全深入理解和吸收了Kafka的源码和设计。
还有一个项目叫jocko[链接参考上图],它是Kafka的golang语言克隆版(不是简单克隆,还做了简化和优化),是由一个叫Travis Jeffery的老外开发的。jocko这个项目比较成功,目前在github上有3.9k星,在业界有不少公司在用。也就是说,通过jocko克隆项目,Travis Jeffery不仅深入理解了Kafka的源码和设计,还给社区贡献了价值。
另外,波波早年也曾尝试开发过Kafak的简化版,起名叫Luxun[链接参考上图]。虽然这个项目没有持续下去,但是经过这次克隆,波波也已经深入理解了Kafka的源码和设计(早期0.7版本)。
方法4一定有克隆版产出,放在github上可以获得社区反馈。通过对知名的、高质量的开源项目进行模仿克隆,不仅可以提升源码阅读的能力,同时可以快速提升技术和项目开发技能。总体上,方法4的学习效果可以达到5~10的水平。如果大家平时在公司没有机会接触到高质量/高价值的项目,那么方法4,是波波推荐大家学习的一种方法。当然,具体去克隆项目的时候,你要量力而行,选择适合自己当前技能水平的开源项目,因为大部分成功的开源项目都非常复杂。
方法5 ~ 生产化落地
方法5叫生产化落地,它更进一步,达到第4层,如下表所示:
方法5指的是在整理开源项目代码和输出分享的基础上,再在企业生产级项目中进行落地,项目要承担实际业务流量。后续根据业务需要,对项目进行进一步定制优化。甚至还可以再进一步,在完全吸收开源项目的基础上,进行创新自研。
方法5的学习效果是非常好的,通过这个方法学到的东西,是在企业里头真刀真枪落地过的。一般通过企业级实战项目获得的经验,都会令你终生难忘。波波之前在企业工作的过程中,多次采用方法5,落地过很多重要项目。
其中一个是携程的Zuul网关项目。记得在2013年左右的时候,携程就启动了无线优先(Mobile First)战略,在业务上获得了巨大成功。但是刚开始,携程的无线API是一个耦合的单体服务,前面是没有网关,直接对外暴露服务的。为了支持无线API的解耦拆分,我当时主导了携程无线API网关的研发工作。那段时间,我曾经一度是Netflix开源文化的重度粉丝,花了大量时间研究Netflix的开源项目,其中包括Zuul网关。经过调研,我发现Zuul网关可以引入携程,解决无线API解耦拆分的问题。于是,我花了大致半个月的时间,把Netflix Zuul网关源码都整理了一遍(Zuul网关的源码其实并不复杂,整理过的源码可以参考上图的链接),单元测试全部跑通,然后在技术部门做了关于Zuul网关的技术分享。之后,我们团队就立项,正式启动将Zuul网关引入携程,并且最终在生产上成功落地下来。后续实践证明,Zuul网关为携程无线API的解耦拆分,还有携程后台的微服务化,都立下了汗马功劳。当然,在生产落地的过程中,根据携程的具体业务需要,我们对Zuul网关的源码(包括过滤器),都进行了深度定制。记得当时我们还专门开发了一个TCP版的Zuul网关,因为携程老的无线App是基于TCP协议定制的。经过这次大项目,我不仅深入理解了Zuul网关的设计和代码,同时提升了生产级项目的落地能力。当然,我还给携程贡献了一个非常有价值的产品,这个产品目前还是携程的核心基础服务,承载超过每日百亿级的API流量。
关于携程Zuul网关的项目经验,我后来总结在了《微服务架构实践160讲》这门课程当中。目前,这门课在极客时间上的订阅量已经过万。
类似的例子还有很多。比方说,当时为了解决携程微服务不稳定的问题,我还主导引入了Netflix的Hystrix开源限流熔断组件。由于当时携程的大部分微服务还是基于微软.Net技术栈的,但原版的Hystrix是基于Java的,为了能够落地,我还是先把Hystrix的源码整理+输出/分享后,再带领团队研发了基于.Net版本的CHystrix产品[链接参考上图],也获得较大成功。
另外在拍拍贷的时候,在吸收了Kafka等主流消息队列设计思想的基础上,我带领团队研发了轻量级的PMQ消息系统,为拍拍贷系统的解耦拆分和微服务化,打下了坚实基础。PMQ是一个在吸收开源项目设计思路的基础上,完全创新自研的产品。关于PMQ这个产品的设计和实践经验,我已经输出在《分布式系统案例》这门新课中。该课程刚刚在极客时间平台上发布,上线不到一周,已经有超过2千订阅。
另外还有一个案例值得一提。我在携程时有一个同事叫黄杰,他是专注监控领域的。在携程的时候,他曾参与研发了携程第一代的日志/调用链/Metrics监控系统。后来他去了饿么吗,在饿了么又落地了一整套应用监控系统,具体项目的细节可以参考他在QCon上的ppt分享[链接见上图]。他的路子也是不断吸收并生产化开源项目,他专门研究监控领域的项目,包括像CAT/OpenTSDB/InfluxDB还有Promethues等。他把这些主流开源项目的源码都逐个研究透,然后找机会生产化,再不断定制打磨。去年他还开源了自己的监控产品,叫LinDB。到现在,黄杰已经在监控领域打磨积累了近6年,可以毫不夸张的说,他已经是国内应用监控领域的顶级技术专家了。
生产化落地的学习效果是毋庸置疑的,如果有机会承担公司级的核心项目,那么对你的能力锻炼是全方位的,包括项目实战落地能力,企业级源码阅读和定制能力等等。而且生产化落地一定有价值输出,也一定会有用户反馈(内部或者外部的),有反馈就有持续改进的机会。总之,生产化落地的学习效果可以>10,当然,具体大小要看项目在企业中的关键程度。
方法6 ~ 开发知识产品
方法6叫开发知识产品,它同样在第四层,见下表:
方法6指的是,在将开源项目代码基本吸收的基础上,开发出应用演示项目(或者克隆项目),并制作成知识付费产品(包括书籍或视频等),发布到知识付费平台。
方法6是波波近年在探索的一种方法。比方说,对于前面方法4中提到的Staffjoy项目,在克隆和开源输出的基础上,我又设计和制作了一门叫《Spring Boot 与 Kubernetes 云原生微服务实践》的课程,讲解如何基于Spring Boot和Kubernetes等技术,开发一个小规模的微服务应用。这门课程已经在极客时间平台上输出。这个工作做完,波波不仅在github上分享和沉淀了一个项目(目前有超过1k星),而且还输出和沉淀了一个知识付费产品(目前有超过6k的订购)。同时,在输出的过程中,波波还初步掌握了知识付费产品的设计和开发技能,另外还初步接触了市场研究、客服,还有营销推广等技术之外的新领域。
方法6还有一个比较有意思的案例,是一个叫新峰商城的开源项目[链接见上图],它是一个叫13的高级工程师开发的。这是一个用SpringBoot开发的网上商城演示项目。作者不仅输出了一个可供学习的开源项目,同时还输出了两个知识产品,一个是基于这个项目写了一本付费教程,发布在掘金小册平台上,目前已有9百多人购买;另外一个是他还基于这个项目开发了一个付费视频教程,发布在CSDN学院上,目前已经有超过万人学习(注意这个不是实际购买量)。从这些项目和内容输出可以看出,13不仅是一个具有技术研发能力,还是一个有产品和商业化头脑的工程师。
方法6有知识产品输出,可以获得商业用户的反馈,根据反馈可以持续改进学习。在知识产品输出的过程中,作者不仅要主导产品的设计和开发,还要参与市场调研、客服和推广等活动,几乎可以看作是一种小规模的创业活动。这个过程对作者的能力锻炼也是全方位的,除了技术和项目开发能力,还包括知识产品的设计和开发能力,还有市场调研、客服和营销推广等技能。当然,还可以获得一定的行业影响力。总体上,方法6的学习效果也是>10的。
方法7 ~ 开发自己的开源项目
方法7叫开发自己的开源项目,它属于高级方法,达到第5层,如下表所示:
方法7指的是,在吸收开源项目+企业实践落地的基础上,沉淀出自己的开源项目,并持续推动开源社区建设。
方法7的案例在欧美国家很普遍,在国内还不是很多,但是已经有一些冒芽案例。这些案例中的项目,主要由国内一些优秀的工程师/架构师推动。
第一个案例是宋顺开发的Apollo微服务配置中心项目[链接见上图],这个项目目前在github上已经有超过2万多颗星,是一个非常成功的基础中间件类项目。我的《微服务架构实践160讲》课程中,也专门有一章是讲Apollo的。Apollo是经过携程大规模生产实践落地出来的,宋顺是这个项目的主要开发者,也是这个项目的开源社区的主要维护者。因为Apollo项目,宋顺不仅全面提升了项目开发技能,同时也提升了行业影响力,目前他已经从携程跳到蚂蚁金服去工作。
第二个案例是吴晟开发的Skywalking应用性能监控项目[链接见上图],目前这个项目在github上有超过13.8k星,也是非常成功的。吴晟玩技术的路子有点花,他之前是OneAPM的工程师,在吸收了OneAPM产品的一些设计思路的基础上,他在业余时间开发和开源了Skywalking APM。之后,吴晟跳槽去了华为,期间他还把Skywalking推到了Apache,成了Apache基金会的一个项目。近几年,吴晟又玩到国外去了,加入了一家叫Tetrate的云原生技术公司,继续推进他的Skywalking项目。吴晟年龄并不大,背景也不是特别突出(有兴趣可以看他在github上的个人简历,链接见上图),不过他对开源技术充满激情,也比较会玩技术。
第三个案例是LinDB[链接见上图],就是方法5中提到的黄杰的开源产品。LinDB是一个类似InfluxDB的时间序列监控产品,但是支持分布式的,目前LinDB在github上有近1.5k星。黄杰目前已经从饿了么跳去字节跳动工作,仍然专注于他热衷的应用监控领域。
上面这几个工程师/架构师都是国内开源领域的佼佼者,他们都是在吸收开源项目+企业实践落地的基础上,沉淀出自己的开源项目,并不断推进开源社区的建设。这几个人在国内互联网行业已经产生了不小的影响力(影响力指数基本上可以用github上星的数量来衡量),他们找工作一般也不需要投简历,因为github上的项目就是他们最好的简历,除了大量的猎头,很多大厂的HR甚至会主动去"勾搭"他们。
如果你对开源技术充满热情,技术功底也不错,但是觉得目前企业中的项目挑战性还不够,那么方法7是波波推荐你尝试的方法。当然,方法7对你的技术和开发能力的要求非常高,时间精力的投入也非常大,所以也要量力而行。
方法7有产品价值输出,有社区反馈,根据反馈可以持续改进。它不仅可以提升你的技术和项目开发技能,也可以锻炼你的开源和社区运营技能。另外,成功的开源项目可以给社区贡献价值,同时大大提升你的行业影响力。总体上,方法7的学习效果也是>10的。
方法8 ~ 商业化自己的开源项目
方法8叫商业化自己的开源项目,它处在顶层第六层,见下表所示:
方法8指的是,在自己的开源产品的基础上,持续推进社区生态建设,并逐步走上商业化服务的道路,甚至开创一个公司。
方法8对大部分开发者来说是遥不可及的,国内外能走到这一步的顶级工程师/架构师也寥寥可数。考虑到方法8非常难,我这里只是简单举几个经典案例,这些案例的创始人都是从开源项目开始,然后不断打磨优化产品,持续投入社区生态建设,并最终走上商业化的道路。
第一个案例是TiDB,一个开源的分布式NewSQL数据库,作者是国内的黄东旭,他也是著名开源项目codis的主要作者。目前,TiDB已经走上企业服务道路,背后公司是PingCAP,黄东旭是CEO。2018.9月PingCAT获得C轮5千万美金的融资。
第二个案例是业界知名的Kafka开源消息队列,主要作者是三个人,一个美国人Jay Kreps+一个中国人Jun Rao+一个印度人Neha Narkhede,是一个很有意思的三人组合。Kafka大致是在2011年初,从Linkedin落地后开源出来。2014年底,三个作者从Linkedin出来,成立了一个叫Confluent的公司,专注kafka的社区推广和商业化。2019.1月,Confluent获得D轮1.25亿美金融资,公司估值25亿美金左右。
第三个案例是Sentry异常日志监控开源项目,和这个项目对应的公司就叫Sentry,两个创始人分别是David Cramer和Chris Jennings。原来两人都是美国Disqus公司的软件工程师,他们从一个异常日志监控小工具做起,不断打磨积累,后来做成SaaS服务公司,走上商业化道路。经过近10年的积累,目前Sentry公司有近100人团队规模。2019.9月,Sentry获得C轮4千万美金融资。
方法8有开源和商业化的产品输出,同时完全和企业级客户闭环,可以说是开源学习的终极方法。通过方法8,创始人可以同时获得产品化和商业化技能,社区生态建设技能,还有技术领导力等全方位的技能,可以说,方法8的总体学习效果超过100。
三、要点心得
好,上面我把学习开源的8种方法(包括6个层次),给大家全都介绍完了,下面我来做一个要点心得总结。尽管上面的内容很多,但是这些要点才是需要大家take away(记住带走)的,见下图:
首先第一点是输入要有输出,学习要有产出。不管你学哪种技术,或者学哪个开源项目,最终都要有个产出。这个产出可以是一个ppt+一次技术分享、也可以是一篇文章或一个视频教程,当然也可以是一个落地的企业项目,等等。没有产出的学习,一般效果都比较差。
其次是闭环反馈+持续改进。精益创业(Lean Startup)提出了一个方法论,叫构建(Build)->测量(Measure)->学习(Learn)环,见上图所示,这个环主要是用于指导快速产品开发和创业的。如果把这个环顺时针旋转约45度,就变成了学习(Learn)->构建(Build)->测量(Measure)环。也就是说,你要学点什么东西,一定要构造产出点什么东西,然后要找用户用你的这个东西,之后你就可以根据用户的反馈改进你的学习,从而形成一个正向的、可以持续改进的循环。一般用户越多,反馈就越多,学习效果也就越好。最好你能够量化你的学习效果,比方说github上星的数量,或者B站上视频的点击/获赞量等。
第三、有个哲学家曾经说过:“如果你要真正理解某人或者某事,那么就尝试去改变他/他/它”。学习开源项目也是一样的,如果你不曾亲自动手去修改过开源项目的代码(包括定制扩展或者克隆等),那么你不可能真正深入理解一个开源项目。
第四,大家都是学习爱好者,平时都会花大量时间进行学习。既然投入了时间,那么一定要让你的投入产生比最大化,说白了是要一举要多得。波波就是这样的,一旦下定决心投入时间精力去学习某个东西,那么一定要有价值产出,这个产出一定要变成自己的个人沉淀积累,并且这个产出最好要能贡献社区(对社区有价值),然后能提升自己的影响力,最后能真正的学到东西。当你养成以投入产出比的视角去看待学习以后,你就会对你的学习投入慎之又慎,不会轻易投入价值小的学习方式。
最后要强调一点,不管是学技术,学英语,做开源,还是做视频课程,都遵循所谓的复利曲线,如上图所示。在复利曲线的底部,成本线以下的那条成长线很平很长,只有到达拐点,成长线才会呈指数级上升。比方说,波波投入技术领域已经超过15年,只是在最近几年,才隐约感觉快到拐点附近了。另外波波发现,在YouTube上做视频输出的比较成功的大V,平均积累周期是5~6年,才会出现拐点,订阅量呈现快速增长。对于方法8提到的从开源到商业公司的案例,底部的成长线更长,一般周期需要超过10,才可能盈利甚至上市。
所以,如果你想今年学个什么技术,明年就想成为技术大牛的,那么波波劝你不要学技术,去炒股炒房子或者买彩票,同样的时间周期,可能成功概率会更大:)
往期推荐
技术琐话
以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。本号由坐馆老司机技术团队维护。